home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr07 / oleo130s.zip / OLEO130S.TAR / oleo-1.3 / key.c < prev    next >
C/C++ Source or Header  |  1993-03-30  |  10KB  |  474 lines

  1. /*    Copyright (C) 1993 Free Software Foundation, Inc.
  2.  
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7.  
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. GNU General Public License for more details.
  12.  
  13. You should have received a copy of the GNU General Public License
  14. along with this software; see the file COPYING.  If not, write to
  15. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  16.  
  17. #include <ctype.h>
  18.  
  19. #include "key.h"
  20. #include "cmd.h"
  21. #include "io-abstract.h"
  22. #include "io-generic.h"
  23. #include "io-utils.h"
  24. #include "io-term.h"
  25.  
  26. struct keymap **the_maps;
  27. char **map_names;
  28. char **map_prompts;
  29. int num_maps;
  30. struct cmd_func **the_funcs;
  31. int num_funcs;
  32.  
  33.  
  34. #ifdef __STDC__
  35. int
  36. search_map_for_cmd (struct line * line, int map, int vec, int code)
  37. #else
  38. int
  39. search_map_for_cmd (line, map, vec, code)
  40.      struct line * line;
  41.      int map;
  42.      int vec;
  43.      int code;
  44. #endif
  45. {
  46.   int len = strlen (line->buf);
  47.   struct keymap * this_map;
  48.   int x;
  49.   char used[256];
  50.   int try_prefix;
  51.  
  52.   for (try_prefix = 0; try_prefix < 2; ++try_prefix)
  53.     {
  54.       bzero (used, sizeof (used));
  55.  
  56.       for (this_map = the_maps[map]; this_map; this_map = this_map->map_next)
  57.     {
  58.       for (x = 128; x >= 0; --x)
  59.         if (!used[x])
  60.           {
  61.         int found_it = ((this_map->keys[x].vector == vec)
  62.                 && this_map->keys[x].code == code);
  63.         int prefix_key = ((this_map->keys[x].vector == -1)
  64.                   && (this_map->keys[x].code != -1));
  65.         if (!(   (this_map->keys[x].vector == -1)
  66.               && (this_map->keys[x].code == -1)))
  67.           used[x] = 1;
  68.         if (found_it || (try_prefix && prefix_key))
  69.           {
  70.             char * c = char_to_string (x);
  71.             catn_line (line, " ", 1);
  72.             catn_line (line, c, strlen (c));
  73.             if (found_it
  74.             || (try_prefix
  75.                 && search_map_for_cmd (line,
  76.                            this_map->keys[x].code,
  77.                            vec, code)))
  78.               return 1;
  79.             line->buf[len] = 0;
  80.           }
  81.           }
  82.     }
  83.     }
  84.   return 0;
  85. }
  86.  
  87. #ifdef __STDC__
  88. static void 
  89. do_bind_key (struct keymap *m, int key, int vector, int code)
  90. #else
  91. static void 
  92. do_bind_key (m, key, vector, code)
  93.      struct keymap *m;
  94.      int key;
  95.      int vector;
  96.      int code;
  97. #endif
  98. {
  99.   m->keys[key].vector = (short)vector;
  100.   m->keys[key].code = (short)code;
  101. }
  102.  
  103.  
  104. #ifdef __STDC__
  105. void 
  106. bind_key (char * keymap, char * function, int ch)
  107. #else
  108. void 
  109. bind_key (keymap, function, ch)
  110.      char * keymap;
  111.      char * function;
  112.      int ch;
  113. #endif
  114. {
  115.   struct cmd_func * tmpfunc;
  116.   int map = map_id (keymap);
  117.   int vec;
  118.   int code;
  119.   struct rng rng;
  120.   struct cmd_func * cmd;
  121.  
  122.   if (map < 0)
  123.     {
  124.       io_error_msg ("bind_key: bad keymap.");
  125.       return;
  126.     }
  127.  
  128.   if (!find_func (&vec, &cmd, function))
  129.     {
  130.       code = (cmd - the_funcs[vec]);
  131.       goto fini;
  132.     }
  133.  
  134.   for (code = 0; code < num_maps; code++)
  135.     {
  136.       if (!strcmp (function, map_names[code]))
  137.     {
  138.       vec = -1;
  139.       goto fini;
  140.     }
  141.     }
  142.   if (get_abs_rng (&function, &rng))
  143.     {
  144.       io_error_msg ("Unknown command '%s'", function);
  145.       return;
  146.     }
  147.  
  148.   for (code = 0; code < n_bound_macros; code++)
  149.     {
  150.       if (!bcmp (&bound_macros[code], &rng, sizeof (struct rng)))
  151.       goto fini;
  152.     }
  153.  
  154.   function = range_name (&rng);
  155.   if (!bound_macro_vec)
  156.     {
  157.       bound_macros = ck_malloc (sizeof (struct rng));
  158.       n_bound_macros = 1;
  159.       tmpfunc = (struct cmd_func *)ck_malloc (2 * sizeof (struct cmd_func));
  160.       bzero (tmpfunc + 1, sizeof (*tmpfunc));
  161.       bound_macro_vec = add_usr_cmds (tmpfunc);
  162.     }
  163.   else
  164.     {
  165.       n_bound_macros++;
  166.       bound_macros = ck_realloc (bound_macros,
  167.                  n_bound_macros * sizeof (struct rng));
  168.       the_funcs[bound_macro_vec]
  169.     = ck_realloc (the_funcs[bound_macro_vec],
  170.               (1 + n_bound_macros) * sizeof (struct cmd_func));
  171.       tmpfunc = &the_funcs[bound_macro_vec][n_bound_macros - 1];
  172.       bzero (tmpfunc + 1, sizeof (*tmpfunc));
  173.     }
  174.   vec = bound_macro_vec;
  175.   bound_macros[n_bound_macros - 1] = rng;
  176.   tmpfunc->func_args = (char **)ck_malloc (2 * sizeof (char *));
  177.   tmpfunc->func_args[0] = mk_sprintf ("#%d", n_bound_macros - 1);
  178.   tmpfunc->func_args[1] = 0;
  179.   tmpfunc->init_code = 0;
  180.   tmpfunc->func_doc = 0;
  181.   tmpfunc->func_name = ck_savestr (function);
  182.   tmpfunc->func_func = bound_macro;
  183. fini:
  184.   do_bind_key (the_maps[map], ch, vec, code);
  185. }
  186.  
  187. #ifdef __STDC__
  188. void
  189. bind_set (char * keymap, char * command, char * keyset)
  190. #else
  191. void
  192. bind_set (keymap, command, keyset)
  193.      char * keymap;
  194.      char * command;
  195.      char * keyset;
  196. #endif
  197. {
  198.   int first;
  199.   int last;
  200.   first = string_to_char (&keyset);
  201.   if (first < 0)
  202.     {
  203.       io_error_msg ("Invalid character set.");
  204.       return;
  205.     }
  206.   while (isspace (*keyset))
  207.     ++keyset;
  208.   if (*keyset == '-')
  209.     {
  210.       ++keyset;
  211.       last = string_to_char (&keyset);
  212.       if (last < 0)
  213.     {
  214.       io_error_msg ("Unterminated character set.");
  215.       return;
  216.     }
  217.     }
  218.   else if (*keyset)
  219.     {
  220.       io_error_msg ("Extra characters in keyset: `%s'.",
  221.             keyset);
  222.       return;
  223.     }
  224.   else
  225.     last = first;
  226.   
  227.   while (first <= last)
  228.     {
  229.       bind_key (keymap, command, first);
  230.       ++first;
  231.     }
  232. }
  233.  
  234.  
  235. #ifdef __STDC__
  236. void 
  237. bind_all_keys (char * keymap, char * function)
  238. #else
  239. void 
  240. bind_all_keys (keymap, function)
  241.      char * keymap;
  242.      char * function;
  243. #endif
  244. {
  245.   struct cmd_func * tmpfunc;
  246.   int map = map_id (keymap);
  247.   int vec;
  248.   int code;
  249.   struct rng rng;
  250.   struct cmd_func * cmd;
  251.  
  252.   if (map < 0)
  253.     {
  254.       io_error_msg ("bind_key: bad keymap.");
  255.       return;
  256.     }
  257.  
  258.   if (!find_func (&vec, &cmd, function))
  259.     {
  260.       code = (cmd - the_funcs[vec]);
  261.       goto fini;
  262.     }
  263.  
  264.   for (code = 0; code < num_maps; code++)
  265.     {
  266.       if (!strcmp (function, map_names[code]))
  267.     {
  268.       vec = -1;
  269.       goto fini;
  270.     }
  271.     }
  272.   if (get_abs_rng (&function, &rng))
  273.     {
  274.       io_error_msg ("Unknown command '%s'", function);
  275.       return;
  276.     }
  277.  
  278.   vec = bound_macro_vec;
  279.   for (code = 0; code < n_bound_macros; code++)
  280.     {
  281.       if (!bcmp (&bound_macros[code], &rng, sizeof (struct rng)))
  282.       goto fini;
  283.     }
  284.  
  285.   function = range_name (&rng);
  286.   if (!bound_macro_vec)
  287.     {
  288.       bound_macros = ck_malloc (sizeof (struct rng));
  289.       n_bound_macros = 1;
  290.       tmpfunc = (struct cmd_func *)ck_malloc (2 * sizeof (struct cmd_func));
  291.       bzero (tmpfunc + 1, sizeof (*tmpfunc));
  292.       bound_macro_vec = add_usr_cmds (tmpfunc);
  293.     }
  294.   else
  295.     {
  296.       n_bound_macros++;
  297.       bound_macros = ck_realloc (bound_macros,
  298.                  n_bound_macros * sizeof (struct rng));
  299.       the_funcs[bound_macro_vec]
  300.     = ck_realloc (the_funcs[bound_macro_vec],
  301.               (1 + n_bound_macros) * sizeof (struct cmd_func));
  302.       tmpfunc = &the_funcs[bound_macro_vec][n_bound_macros - 1];
  303.       bzero (tmpfunc + 1, sizeof (*tmpfunc));
  304.     }
  305.   bound_macros[n_bound_macros - 1] = rng;
  306.   tmpfunc->func_args = (char **)ck_malloc (2 * sizeof (char *));
  307.   tmpfunc->func_args[0] = mk_sprintf ("#%d", n_bound_macros - 1);
  308.   tmpfunc->func_args[1] = 0;
  309.   tmpfunc->func_doc = 0;
  310.   tmpfunc->func_name = ck_savestr (function);
  311.   tmpfunc->func_func = bound_macro;
  312. fini:
  313.   {
  314.     int ch;
  315.     for (ch = 0; ch < 256; ++ch)
  316.       do_bind_key (the_maps[map], ch, vec, code);
  317.   }
  318. }
  319.  
  320.  
  321. #ifdef __STDC__
  322. void 
  323. write_keys_cmd (FILE *fp)
  324. #else
  325. void 
  326. write_keys_cmd (fp)
  327.      FILE *fp;
  328. #endif
  329. {
  330.   struct keymap *map;
  331.   int n;
  332.   int key;
  333.   int vec;
  334.   int code;
  335.  
  336.   for (n = 0; n < num_maps; n++)
  337.     {
  338.       char *def;
  339.       map = the_maps[n];
  340.       def = 0;
  341.       if (map && map->map_next)
  342.     {
  343.       for (key = 0; key < num_maps; key++)
  344.         if (the_maps[key] == map->map_next)
  345.           {
  346.         def = map_names[key];
  347.         break;
  348.           }
  349.     }
  350.       if (def)
  351.     fprintf (fp, "create-keymap %s %s\n", map_names[n], def);
  352.       else
  353.     fprintf (fp, "create-keymap %s\n", map_names[n]);
  354.     }
  355.   for (n = 0; n < num_maps; n++)
  356.     {
  357.       map = the_maps[n];
  358.       for (key = 0; key < 256; key++)
  359.     {
  360.       vec = map->keys[key].vector;
  361.       code = map->keys[key].code;
  362.       if (vec < 0 && code >= 0)
  363.         fprintf (fp, "bind-key %s %s %s\n",
  364.              map_names[n],
  365.              map_names[code],
  366.              char_to_string (key));
  367.       else if (vec >= 0)
  368.         fprintf (fp, "bind-key %s %s %s\n",
  369.              map_names[n],
  370.              the_funcs[vec][code].func_name,
  371.              char_to_string (key));
  372.     }
  373.     }
  374. }
  375.  
  376.  
  377.  
  378. #ifdef __STDC__
  379. void 
  380. clear_keymap (struct keymap *m)
  381. #else
  382. void 
  383. clear_keymap (m)
  384.      struct keymap *m;
  385. #endif
  386. {
  387.   int n;
  388.   for (n = 0; n < 256; n++)
  389.     {
  390.       m->keys[n].vector = -1;
  391.       m->keys[n].code = -1;
  392.     }
  393. }
  394.  
  395. #ifdef __STDC__
  396. int 
  397. map_idn (char *name, int n)
  398. #else
  399. int 
  400. map_idn (name, n)
  401.      char *name;
  402.      int n;
  403. #endif
  404. {
  405.   int x;
  406.   for (x = 0; x < num_maps; ++x)
  407.     if (!strincmp (name, map_names[x], n))
  408.       return x;
  409.   return -1;
  410. }
  411.  
  412. #ifdef __STDC__
  413. void
  414. create_keymap (char * mapname, char * parentname)
  415. #else
  416. void
  417. create_keymap (mapname, parentname)
  418.      char * mapname;
  419.      char * parentname;
  420. #endif
  421. {
  422.   int map = map_id (mapname);
  423.   int parent = parentname ? map_id (parentname) : -1;
  424.  
  425.   if (map > 0)
  426.     {
  427.       io_info_msg ("Map %s already exists.",  mapname);
  428.       return;
  429.     }
  430.   if (parentname && (parent < 0))
  431.     {
  432.       io_error_msg ("Map %s does not exist.", parentname);
  433.       return;
  434.     }
  435.   the_maps = ck_realloc (the_maps, (num_maps + 1) * sizeof (struct keymap *));
  436.   the_maps[num_maps] = ck_malloc (sizeof (struct keymap));
  437.   the_maps[num_maps]->id = num_maps;
  438.   the_maps[num_maps]->map_next = ((parent >= 0)
  439.                   ? the_maps[parent]
  440.                   : 0);
  441.   {
  442.     int c;
  443.     for (c = 0; c < 256; ++c)
  444.       {
  445.     the_maps[num_maps]->keys[c].vector = -1;
  446.     the_maps[num_maps]->keys[c].code = -1;
  447.       }
  448.   }
  449.   map_names = ck_realloc (map_names, (num_maps + 1) * sizeof (char *));
  450.   map_prompts = ck_realloc (map_prompts, (num_maps + 1) * sizeof (char *));
  451.   map_names[num_maps] = ck_savestr (mapname);
  452.   map_prompts[num_maps] = 0;
  453.   num_maps++;
  454. }
  455.  
  456.  
  457. #ifdef __STDC__
  458. void
  459. set_map_prompt (char * map, char * str)
  460. #else
  461. void
  462. set_map_prompt (map, str)
  463.      char * map;
  464.      char * str;
  465. #endif
  466. {
  467.   int id = map_id (map);
  468.   if (id < 0)
  469.     io_error_msg ("No such keymap as %s.", map); /* No return. */
  470.   if (map_prompts[id])
  471.     free (map_prompts [id]);
  472.   map_prompts[id] = ck_savestr (str);
  473. }
  474.